package cn.virens.common.utils.common;

import cn.hutool.core.date.DateUtil;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期工具类
 *
 * @author : virens
 */
public class CalendarUtil {
    public static final String Y = "yyyy";
    public static final String YM = "yyyy-MM";
    public static final String YMD = "yyyy-MM-dd";
    public static final String YMD_HMS = "yyyy-MM-dd HH:mm:ss";
    public static final String HMS = "HH:mm:ss";
    public static final String FORMAT_DEFAULT = "未知";

    private CalendarUtil() {
    }

    /**
     * 复制一个日期
     *
     * @param year       年
     * @param month      月
     * @param dayOfMonth 日
     * @return Calendar
     */
    public static Calendar clone(int year, int month, int dayOfMonth) {
        return new GregorianCalendar(year, month - 1, dayOfMonth);
    }

    /**
     * 复制一个日期
     *
     * @param calendar calendar value
     * @return Calendar
     */
    public static Calendar clone(Calendar calendar) {
        Calendar result = Calendar.getInstance(calendar.getTimeZone());
        result.setTimeInMillis(calendar.getTimeInMillis());

        return result;
    }

    /**
     * 复制一个日期
     *
     * @param date date value
     * @return Calendar
     */
    public static Calendar clone(Date date) {
        Calendar result = Calendar.getInstance();
        result.setTime(date);

        return result;
    }

    /**
     * 判断 - c1 在 c2 之后
     *
     * @param c1 time a
     * @param c2 time b
     * @return boolean
     */
    public static boolean after(Object c1, Object c2) {
        long t1 = 0;
        long t2 = 0;

        if (c1 instanceof Date) {
            t1 = ((Date) c1).getTime();
        } else if (c1 instanceof Calendar) {
            t1 = ((Calendar) c1).getTimeInMillis();
        } else {
            return false;
        }

        if (c2 instanceof Date) {
            t2 = ((Date) c2).getTime();
        } else if (c1 instanceof Calendar) {
            t2 = ((Calendar) c2).getTimeInMillis();
        } else {
            return false;
        }

        return t1 > t2;
    }

    /**
     * 判断 - c1 在 c2 之前
     *
     * @param c1 time a
     * @param c2 time b
     * @return boolean
     */
    public static boolean before(Object c1, Object c2) {
        long t1 = 0;
        long t2 = 0;

        if (c1 instanceof Date) {
            t1 = ((Date) c1).getTime();
        } else if (c1 instanceof Calendar) {
            t1 = ((Calendar) c1).getTimeInMillis();
        } else {
            return false;
        }

        if (c2 instanceof Date) {
            t2 = ((Date) c2).getTime();
        } else if (c1 instanceof Calendar) {
            t2 = ((Calendar) c2).getTimeInMillis();
        } else {
            return false;
        }

        return t1 < t2;
    }

    /**
     * 判断是不同一年
     *
     * @param calendar1 date a
     * @param calendar2 date b
     * @return boolean
     */
    public static boolean isSameYear(Calendar calendar1, Calendar calendar2) {
        if (calendar1 == null) return false;
        if (calendar2 == null) return false;

        int y1 = calendar1.get(Calendar.YEAR);
        int y2 = calendar2.get(Calendar.YEAR);

        return y1 == y2;
    }

    /**
     * 判断是不是上一个月
     *
     * @param calendar1 当前月份
     * @param calendar2 被判定月份
     * @return boolean
     */
    public static boolean isPrevMonth(Calendar calendar1, Calendar calendar2) {
        Calendar calendar = CalendarUtil.clone(calendar2);
        calendar.add(Calendar.MONTH, 1);

        return isSameYear(calendar1, calendar);
    }

    /**
     * 判断是不同一月
     *
     * @param calendar1 date a
     * @param calendar2 date b
     * @return boolean
     */
    public static boolean isSameMonth(Calendar calendar1, Calendar calendar2) {
        if (!isSameYear(calendar1, calendar2)) return false;

        int m1 = calendar1.get(Calendar.MONTH);
        int m2 = calendar2.get(Calendar.MONTH);

        return m1 == m2;
    }

    /**
     * 判断是不是下一个月
     *
     * @param calendar1 当前月份
     * @param calendar2 被判定月份
     * @return boolean
     */
    public static boolean isNextMonth(Calendar calendar1, Calendar calendar2) {
        Calendar calendar = CalendarUtil.clone(calendar2);
        calendar.add(Calendar.MONTH, -1);

        return isSameMonth(calendar1, calendar);
    }

    /**
     * 判断是昨天
     *
     * @param calendar1 当前日期
     * @param calendar2 被判定日期
     * @return boolean
     */
    public static boolean isPrevDay(Calendar calendar1, Calendar calendar2) {
        Calendar calendar = CalendarUtil.clone(calendar2);
        calendar.add(Calendar.DAY_OF_MONTH, 1);

        return isSameDay(calendar1, calendar);
    }

    /**
     * 判断是不是同一天
     *
     * @param date1 date a
     * @param date2 date b
     * @return boolean
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null) return false;
        if (date2 == null) return false;

        Calendar calendar1 = clone(date1);
        Calendar calendar2 = clone(date2);

        return isSameDay(calendar1, calendar2);
    }

    /**
     * 判断是不同一日
     *
     * @param calendar1 date a
     * @param calendar2 data b
     * @return boolean
     */
    public static boolean isSameDay(Calendar calendar1, Calendar calendar2) {
        if (!isSameMonth(calendar1, calendar2)) return false;

        int d1 = calendar1.get(Calendar.DAY_OF_MONTH);
        int d2 = calendar2.get(Calendar.DAY_OF_MONTH);

        return d1 == d2;
    }

    /**
     * 判断是明天
     *
     * @param calendar1 当前日期
     * @param calendar2 被判定日期
     * @return boolean
     */
    public static boolean isNextDay(Calendar calendar1, Calendar calendar2) {
        Calendar calendar = CalendarUtil.clone(calendar2);
        calendar.add(Calendar.DAY_OF_MONTH, -1);

        return isSameDay(calendar1, calendar);
    }

    /**
     * 将时间格式化
     *
     * @param pattern 格式
     * @return boolean
     */
    public static String format(String pattern) {
        return format(new Date(), pattern);
    }

    /**
     * 将日期格式化
     *
     * @param calendar datetime value
     * @param pattern  格式
     * @return boolean
     */
    public static String format(Calendar calendar, String pattern) {
        return format(calendar.getTime(), pattern);
    }

    /**
     * 将时间格式化
     *
     * @param date    时间
     * @param pattern 格式
     * @return string
     */
    public static String format(Date date, String pattern) {
        if (date == null) return null;
        if (pattern == null) return null;
        if (pattern.isEmpty()) return null;

        return DateUtil.format(date, pattern);
    }

    /**
     * 将字符串 转为 Date
     *
     * @param date    date's string
     * @param pattern 格式
     * @return date
     */
    public static Date parse(String date, String pattern) {
        if (pattern == null || pattern.isEmpty()) return null;
        if (date == null || date.isEmpty()) return null;

        try {
            return DateUtil.parse(date, pattern);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * yyyy-MM-dd 格式化为Date
     *
     * @param date date's string
     * @return date
     */
    public static Date parse(String date) {
        if (date == null || date.isEmpty()) return null;

        if (YMD_HMS.length() == date.length()) {
            return parse(date, YMD_HMS);
        } else {
            return parse(date, YMD);
        }
    }
}
